001    /* $RCSfile: DESOperationModeInitializationVectorSpec.java,v $
002     * $Revision: 1.7 $
003     * $Date: 2002/01/17 19:24:55 $
004     * $Author: uwe $
005     * $State: Exp $
006     *
007     * Created on August 13, 2001 12:42 PM
008     *
009     * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
010     *
011     * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
012     * ServiceProvider is a library, written in JavaTM, that should be 
013     * used in HBCI banking applications (clients and may be servers),
014     * to do cryptographic operations.
015     *
016     * The jhbci library is free software; you can redistribute it and/or
017     * modify it under the terms of the GNU Lesser General Public
018     * License as published by the Free Software Foundation; either
019     * version 2.1 of the License, or (at your option) any later version.
020     *
021     * The jhbci library is distributed in the hope that it will be useful,
022     * but WITHOUT ANY WARRANTY; without even the implied warranty of
023     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
024     * Lesser General Public License for more details.
025     *
026     * You should have received a copy of the GNU Lesser General Public
027     * License along with this library; if not, write to the Free Software
028     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *
030     */
031    
032    package de.cscc.crypto.provider.spec;
033    
034    import java.security.spec.AlgorithmParameterSpec;
035    import java.util.Arrays;
036    
037    import javax.crypto.IllegalBlockSizeException;
038    
039    import de.cscc.crypto.util.ByteUtil;
040    
041    /** 
042     * DES Initialization Vector (64 bit) class.
043     *
044     * <p>This class is immutable.
045     *
046     * @author  <a href=mailto:uwe@cscc.de>Uwe Günther</a>
047     * @version $Revision: 1.7 $
048     */
049    public class DESOperationModeInitializationVectorSpec 
050            implements AlgorithmParameterSpec, Cloneable {
051    
052        /**
053         * The byte[8] long internal data representation of the initialization
054         * vector.
055         */    
056        private byte[] iv = new byte[8];
057    
058        /** 
059         * Creates a new DESOperationModeInitializationVectorSpec. 
060         *
061         * @param iv the initialization vector to set.
062         * @throws IllegalBlockSizeException if length of iv shorter than 8 bytes. 
063         * If it is longer, we use only the first 8 bytes from iv.
064         */
065        public DESOperationModeInitializationVectorSpec(byte[] iv) 
066                throws IllegalBlockSizeException {
067            this(iv, 0);
068        }
069        
070        /** 
071         * Creates a new DESOperationModeInitializationVectorSpec.
072         *
073         * @param iv the initialization vector to set.
074         * @param offset the offset in iv, where iv starts.
075         * @throws IllegalBlockSizeException if length of iv shorter than 
076         * offset+8 bytes. If it is longer, we use only the first 8 bytes from iv, 
077         * starting at offset.
078         */
079        public DESOperationModeInitializationVectorSpec(byte[] iv, int offset) 
080                throws IllegalBlockSizeException {
081            if (iv.length-offset < 8){
082                throw new IllegalBlockSizeException(
083                    "Usable byte range is " + (iv.length-offset) + 
084                    " bytes large, but it should be 8 bytes or larger.");            
085            }
086            System.arraycopy(iv, offset, this.iv, 0, 8);
087        }
088        
089        /**
090         * Creates a new DESOperationModeInitializationVectorSpec from an existing
091         * one. 
092         *
093         * @param iv the initialization vector to set.
094         */
095        public DESOperationModeInitializationVectorSpec
096               (DESOperationModeInitializationVectorSpec  iv) {    
097            System.arraycopy(iv.iv, 0, this.iv, 0, 8);        
098        }
099    
100        /**
101         * Creates and returns a deep copy of this object.
102         *
103         * @return a clone of this instance.
104         * @see java.lang.Cloneable
105         * @exception CloneNotSupportedException if the object's class does not
106         *             support the <code>Cloneable</code> interface. Subclasses
107         *             that override the <code>clone</code> method can also
108         *             throw this exception to indicate that an instance cannot
109         *             be cloned. */
110        public Object clone() throws CloneNotSupportedException {
111            DESOperationModeInitializationVectorSpec result = 
112                    (DESOperationModeInitializationVectorSpec) super.clone();
113            result.iv = (byte[]) this.iv.clone();
114            return result;
115        }
116        
117        /** 
118         * Indicates whether some other object is "equal to" this one.
119         *
120         * @param   obj   the reference object with which to compare.
121         * @return  <code>true</code> if this object is the same as the obj
122         *         argument; <code>false</code> otherwise.
123         * @see     #hashCode()
124         * @see     java.util.Hashtable
125         */
126        public boolean equals(Object obj) {
127            //Only for performance.
128            if (this == obj) {
129                return true;
130            } 
131            
132            //If obj == null then instanceof returns false, see JLS 15.20.2
133            if (!(obj instanceof DESOperationModeInitializationVectorSpec)) {            
134                return false;
135            }
136            
137            DESOperationModeInitializationVectorSpec other = 
138                    (DESOperationModeInitializationVectorSpec) obj;
139            return Arrays.equals(this.iv, other.iv);
140        }
141        
142        /**
143         * Returns a hash code value for the object. 
144         *
145         * @return  a hash code value for this object.
146         * @see     #equals(java.lang.Object)
147         * @see     java.util.Hashtable
148         */
149        public int hashCode() {
150            int result = 17;
151            for (int i = 0; i < this.iv.length; i++) {
152                result = 37*result + this.iv[i];
153            }
154            return result;
155        }
156        
157        /**
158         * Returns a string representation of the object. 
159         *
160         * @return  a string representation of the object.
161         */
162        public String toString() {
163            return ByteUtil.toHex(this.iv);
164        }
165        
166        /**
167         * Returns the initialization vector.
168         *
169         * @return a initialization vector as byte[8].
170         */
171        public byte[] getIv() {
172            return (byte[]) this.iv.clone();
173        }
174    }